﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Excel = Microsoft.Office.Interop.Excel;

namespace VBOX
{
    class GB17691
    {
        public static readonly string[] ParaName = {
            "是否补传",
            "VIN",
            "GPS时间",
            "故障码",
            "车速（km/h）",
            "大气压（kpa）",
            "实际扭矩",
            "摩擦扭矩",
            "发动机转速",
            "燃料流量（L/h）",
            "SCR上游nox（ppm）",
            "SCR下游nox（ppm）",
            "反应剂余量",
            "进气量（kg/h）",
            "scr入口温度",
            "scr出口温度",
            "DPF压差（kpa）",
            "冷却液温度",
            "油箱液位",
            "定位状态",
            "经度",
            "纬度",
            "总里程（km）"
        };

        public static int line_num = 1;
        public static Excel.Application excelApp;
        public static Excel.Workbooks workbooks;
        public static Excel.Workbook workbook;
        public static Excel.Worksheet worksheet;
        public static byte[] des;
        public static byte[] src;
        public static byte[] vin;
        public static UInt32 temp_32 = 0;
        public static UInt16 temp_16 = 0;
        public static byte temp_8 = 0;
        public static float temp_float = 0;
        public static int index = 0;
        public static int offset = 0;
        public static string gps_time = null;
        public static string dtc = null;
        public static string tmp_dtc = null;

        public static void gb17691_init()
        {
            excelApp = new Excel.Application();
            excelApp.Visible = false;

            workbooks = excelApp.Workbooks;
            workbook = workbooks.Add(true);

            //选择一个sheet
            worksheet = workbook.Sheets[1];

            //填写表头
            line_num = 1;
            for (int i = 0; i < GB17691.ParaName.Length; i++)
                worksheet.Cells[line_num, 1 + i] = GB17691.ParaName[i];

            des = new byte[2048];
            src = new byte[2048];
            vin = new byte[17];
        }

        public static void gb17691_finish(string path)
        {
            //保存写入的数据，这里还没有保存到磁盘
            workbook.Saved = true;

            //生成的excel文件保存在同目录下相同名字前缀
            int index = path.IndexOf(".");
            string tempPath = path.Substring(0, index);
            string savePath = tempPath.Insert(index ,"_" + DateTime.Now.ToString("yyMMddHHmmss") + ".xlsx");

            workbook.SaveCopyAs(savePath);
            workbook.Close();
            excelApp.Quit();

            System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook);
            System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApp);
            GC.Collect();
        }

        public static void gb17691_analysis(string data)
        {
            if (data.Length < 25)
                return;

            index = data.IndexOf("2323");
            if (index < 0)
            {
                index = data.IndexOf("23 23");
                if (index < 0)
                    return;
            }

            string tmp_src = data.Substring(index);

            for (int i = 0; i < tmp_src.Length; i++)
            {
                src[i] = Convert.ToByte(tmp_src[i]);
            }

            UInt32 hexlen = tools.Ascii2Byte(des, src, (UInt16)(tmp_src.Length));
            if (hexlen == 0xFFFF)
            {
                return;
            }

            if ((des[0] == 0x23) && (des[1] == 0x23))
            {
                //只解析实时数据和盲区数据
                if ((des[2] != 0x02) && (des[2] != 0x03))
                    return;

                byte xor_check = 0;
                for (int i = 2; i < hexlen - 1; i++)
                {
                    xor_check ^= des[i];
                }

                if (xor_check != des[hexlen - 1])
                {
                    return;
                }
                else
                {
                    //清零相关变量
                    index = 0;
                    offset = 0;
                    dtc = null;

                    //行数累加
                    line_num++;

                    //是否补传数据
                    if (des[2] == 0x03)
                        worksheet.Cells[line_num, offset + 1] = "补";

                    //帧头
                    index += 3;

                    offset = 1;//从vin开始

                    //vin
                    for (int i = 0; i < 17; i++)
                        vin[i] = des[index + i];
                    worksheet.Cells[line_num, offset + 1] = Encoding.ASCII.GetString(vin);
                    index += 17;

                    //消息体长度
                    index += 4;

                    //时间
                    gps_time = String.Format("{0:00}-{1:00}-{2:00} {3:00}:{4:00}:{5:00}",des[index + 0], des[index + 1], des[index + 2], des[index + 3], des[index + 4], des[index + 5]);
                    index += 6; 
                    worksheet.Cells[line_num, offset + 2] = gps_time;

                    //消息流水号
                    index += 2; 

                    if (des[index] == 1) //OBD数据
                    {
                        index += 1; //跳过数据类型

                        index += 6; //时间
                        index += 1;
                        index += 1;
                        index += 2;
                        index += 2;
                        index += 17;
                        index += 18;
                        index += 18;
                        index += 36;

                        temp_8 = tools.get_data_uint8(des, ref index);
                        if (temp_8 > 0)
                        {
                            //解析故障码
                            for (int i = 0; i < temp_8; i++)
                            {
                                tmp_dtc = tools.get_data_uint32(des, ref index).ToString("X8");
                                dtc += tmp_dtc + "\r\n";
                            }
                            worksheet.Cells[line_num, offset + 3] = dtc;
                        }
                    }

                    if (des[index] == 2)
                    {
                        index += 1; //跳过数据类型

                        //设置excel项目偏移量
                        offset = 5; //从车速开始

                        index += 6; //时间

                        temp_16 = tools.get_data_uint16(des, ref index);
                        temp_float = (float)(temp_16 / 256); //车速
                        worksheet.Cells[line_num, offset + 0] = temp_float.ToString();

                        temp_8 = tools.get_data_uint8(des, ref index);
                        temp_8 = (byte)(temp_8 / 2); //大气压
                        worksheet.Cells[line_num, offset + 1] = temp_8.ToString();

                        temp_8 = tools.get_data_uint8(des, ref index);
                        temp_8 = (byte)(temp_8 - 125); //实际扭矩
                        worksheet.Cells[line_num, offset + 2] = temp_8.ToString();

                        temp_8 = tools.get_data_uint8(des, ref index);
                        temp_8 = (byte)(temp_8 - 125); //摩擦扭矩
                        worksheet.Cells[line_num, offset + 3] = temp_8.ToString();

                        temp_16 = tools.get_data_uint16(des, ref index);
                        temp_float = (float)(temp_16 * 0.125); //发动机转速
                        worksheet.Cells[line_num, offset + 4] = temp_float.ToString();

                        temp_16 = tools.get_data_uint16(des, ref index);
                        temp_float = (float)(temp_16 * 0.05); //发动机燃料流量
                        worksheet.Cells[line_num, offset + 5] = temp_float.ToString();

                        temp_16 = tools.get_data_uint16(des, ref index);
                        temp_float = (float)(temp_16 * 0.05) - 200; //上游传感器
                        worksheet.Cells[line_num, offset + 6] = temp_float.ToString();

                        temp_16 = tools.get_data_uint16(des, ref index);
                        temp_float = (float)(temp_16 * 0.05) - 200; //下游传感器
                        worksheet.Cells[line_num, offset + 7] = temp_float.ToString();

                        temp_8 = tools.get_data_uint8(des, ref index);
                        temp_8 = (byte)(temp_8 * 0.4); //反应剂余量
                        worksheet.Cells[line_num, offset + 8] = temp_8.ToString() + "%";

                        temp_16 = tools.get_data_uint16(des, ref index);
                        temp_float = (float)(temp_16 * 0.05); //进气量
                        worksheet.Cells[line_num, offset + 9] = temp_float.ToString();

                        temp_16 = tools.get_data_uint16(des, ref index);
                        temp_float = (float)(temp_16 * 0.03125) - 273; //入口温度
                        worksheet.Cells[line_num, offset + 10] = temp_float.ToString();

                        temp_16 = tools.get_data_uint16(des, ref index);
                        temp_float = (float)(temp_16 * 0.03125) - 273; //出口温度
                        worksheet.Cells[line_num, offset + 11] = temp_float.ToString();

                        temp_16 = tools.get_data_uint16(des, ref index);
                        temp_float = (float)(temp_16 * 0.1); //DFP压差
                        worksheet.Cells[line_num, offset + 12] = temp_float.ToString();

                        temp_8 = tools.get_data_uint8(des, ref index);
                        temp_8 = (byte)(temp_8 - 40); //冷却液温度
                        worksheet.Cells[line_num, offset + 13] = temp_8.ToString();

                        temp_8 = tools.get_data_uint8(des, ref index);
                        temp_float = (float)(temp_8 * 0.4); //油箱液位
                        worksheet.Cells[line_num, offset + 14] = temp_float.ToString() + "%";

                        temp_8 = tools.get_data_uint8(des, ref index);
                        worksheet.Cells[line_num, offset + 15] = temp_8.ToString();

                        temp_32 = tools.get_data_uint32(des, ref index);
                        temp_float = (float)(temp_32 * 0.00001); //精度
                        worksheet.Cells[line_num, offset + 16] = temp_float.ToString();

                        temp_32 = tools.get_data_uint32(des, ref index);
                        temp_float = (float)(temp_32 * 0.00001); //纬度
                        worksheet.Cells[line_num, offset + 17] = temp_float.ToString();

                        temp_32 = tools.get_data_uint32(des, ref index);
                        temp_float = (float)(temp_32 * 0.1); //总里程
                        worksheet.Cells[line_num, offset + 18] = temp_float.ToString();
                    }
                    
                }
            }
        }
    }
}
